/**
 * 
 * Copyright 2009, 2010 Mike Jamer [email: mikejamer@gmail.com ]
 * 
 * This File is part of Moose IRC
 * 
 * MooseIRC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * MooseIRC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with MooseIRC.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

using System;
using System.Net;
using System.Net.Sockets;

namespace ident_1
{
	/// <summary>
	/// Ident Server 
	/// </summary>
	internal class IdentServer
	{
        /// <summary>
        /// Primary/Listening Socket
        /// </summary>
        private Socket m_primary_socket;

		/// <summary>
		/// Server Entry Point 
		/// </summary>
		/// <param name="args">
		/// A <see cref="System.String[]"/>
		/// </param>
		public static void Main (string[] args)
		{
			Console.WriteLine ("Ident Server - Prototype 1");

            new IdentServer();

			string input = string.Empty;
			while (input != "quit") {
				Console.Write(">");
				input = Console.ReadLine();
			}
			Console.WriteLine("Press <Enter> to terminate...");
			Console.ReadLine();
		}

        public IdentServer()
        {
            initialize_server();
            return;
        }

        /// <summary>
        /// Initializes the IDENT server
        /// </summary>
        private void initialize_server()
        {
            Console.WriteLine("Initializing Ident Server...");

            EndPoint local_endpoint = null;
            m_primary_socket = create_socket();
            local_endpoint = new IPEndPoint(IPAddress.Any, 113);
            m_primary_socket.Bind(local_endpoint);
            m_primary_socket.Listen(1);
            m_primary_socket.BeginAccept(onAcceptComplete, null);

            Console.WriteLine("Initializing Complete...");

            return;
        }

        /// <summary>
        /// Createa a new socket
        /// </summary>
        /// <returns>new socket</returns>
        private Socket create_socket()
        {
            return new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Fires when client connects
        /// </summary>
        private void onAcceptComplete(IAsyncResult result)
        {
            TxState tx_state = new TxState(m_primary_socket.EndAccept(result));
            tx_state.socket.BeginReceive(tx_state.buffer, 0, tx_state.buffer.Length, SocketFlags.None, onEndClientRecieve, tx_state);
            Console.WriteLine("Client Connected...");
            return;
        }

        /// <summary>
        /// Fires when recieve from client completes
        /// </summary>
        /// <param name="result"></param>
        private void onEndClientRecieve(IAsyncResult result)
        {
            TxState tx_state = (TxState)result.AsyncState;
            int recv = tx_state.socket.EndReceive(result);

            string message = System.Text.Encoding.UTF8.GetString(tx_state.buffer, 0, recv);
            if (message.Contains(","))
            {
                Console.WriteLine("Ident Requested..");
                string[] ident = message.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                string sendIdent = ident[0].Trim() + ", " + ident[1].Trim() + " : USERID : UNIX : mike!";
                byte[] send = System.Text.Encoding.UTF8.GetBytes(sendIdent);
                tx_state.socket.BeginSend(send, 0, send.Length, SocketFlags.None, onEndClientSend, tx_state);
            }
            tx_state.socket.BeginReceive(tx_state.buffer, 0, tx_state.buffer.Length, SocketFlags.None, onEndClientRecieve, tx_state);
            return;
        }

        /// <summary>
        /// Fires when Ident send is complete
        /// </summary>
        private void onEndClientSend(IAsyncResult result)
        {
            Console.WriteLine("Ident Transmitted..");
            TxState tx_state = (TxState)result.AsyncState;
            int sent = tx_state.socket.EndReceive(result);

            Console.WriteLine("Ident Sent!");

            return;
        }

	}
}
